/*
	Copyright (C) 2010 2011 Rémi Thebault

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef GANTTTASK_H
#define GANTTTASK_H

#include <QDebug>
#include <QObject>
#include <QGraphicsItem>

#include <procycle/task.h>
#include <procycle/cycle.h>

#include "globals.h"
#include "pcchild.h"
#include "ganttitem.h"


class GanttLink;
class GanttMTask;


class GanttTask : public GanttItem
{
public:
	GanttTask(ProCycle* app, PC::Task* task, GanttCycle* gcycle, GanttMTask* parent);
	virtual ~GanttTask();


	PC::Task* task () {
		return m_task;
	}

	QString tbsId() {
		return m_task->tbsId();
	}

	virtual GanttTask* resolvTask(QString tbsId) {
		return 0;
	}

	virtual void resetTask(PC::Task* task) {
		m_task = task;
	}

	QList<GanttLink*> inGLinks();
	QList<GanttLink*> outGLinks();

	virtual void replaceChildren() {}



	bool drawFromStart() {
		return m_drawFromStart;
	}
	void setDrawFromStart(const bool& draw);

	bool drawFromFinish() {
		return m_drawFromFinish;
	}
	void setDrawFromFinish(const bool& draw);

	bool drawToStart() {
		return m_drawToStart;
	}
	void setDrawToStart(const bool& draw);

	bool drawToFinish() {
		return m_drawToFinish;
	}
	void setDrawToFinish(const bool& draw);

	void unsetAllDraws();

	virtual void setZPos(int zPos) {
		setZValue(zPos);
	}

	virtual void setCycleProp(PC::Cycle::Property p, const QVariant& value);
	virtual void editModeChanged();

	bool linksHovered () {
		return m_linksHovered;
	}
	void setLinksHovered (bool hovered);

	bool pointCanHover(const QPointF& point) {
		return pointOnTaskBar(point);
	}

	bool pointCanSelect(const QPointF& point) {
		return pointOnTaskBar(point);
	}

	virtual QRectF fromStartRect();
	virtual QRectF fromFinishRect();
	virtual QRectF toStartRect();
	virtual QRectF toFinishRect();


	virtual int barTop()=0;
	virtual int barHeight()=0;
	virtual int linkDockY()=0;
	virtual int barBottom()=0;

	void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

	virtual void paintTaskBar(QPainter* painter)=0;
	void paintFloat(QPainter* painter);
	void paintTaskName(QPainter* painter, int left, int bottom);
	virtual void paintFromStartDock(QPainter* painter);
	virtual void paintFromFinishDock(QPainter* painter);
	virtual void paintToStartDock(QPainter* painter);
	virtual void paintToFinishDock(QPainter* painter);


	virtual bool pointOnTaskBar(const QPointF& p)=0;

	// tends to make link type finish to start by default
	// with biggers fromFinish and toStart
	virtual bool pointOnFromStart(const QPointF& p) {
		return fromStartRect().contains(p);
	}
	virtual bool pointOnFromFinish(const QPointF& p) {
		return fromFinishRect().contains(p);
	}
	virtual bool pointOnToStart(const QPointF& p) {
		return toStartRect().contains(p);
	}
	virtual bool pointOnToFinish(const QPointF& p) {
		return toFinishRect().contains(p);
	}

	virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
	virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
	virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
	virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
	virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
	virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
	virtual void dropEvent(QGraphicsSceneDragDropEvent *event);

protected:
	virtual void requestSelection(bool selected=true);

	PC::Task*			m_task;

	QRect				m_rect;
	int					m_lateFinish;

	bool				m_drawCriticalPath;
	bool				m_drawTaskFloats;
	bool				m_drawCycleOverlap;
	bool				m_drawTaskName;

	bool				m_drawFromStart;
	bool				m_drawFromFinish;
	bool				m_drawToStart;
	bool				m_drawToFinish;

	bool				m_linksHovered;
};

#endif // GANTTTASK_H
